package com.koron.system.staff.service.impl;

import cn.hutool.core.util.StrUtil;
import com.koron.bean.app.AppSimpleBean;
import com.koron.bean.base.Attachment;
import com.koron.bean.base.Response;
import com.koron.bean.query.PageQuery;
import com.koron.bean.system.agent.po.AgentRoleUserPo;
import com.koron.bean.system.agent.vo.AgentUserVo;
import com.koron.bean.system.org.OrgBean;
import com.koron.bean.system.org.OrgVo;
import com.koron.bean.system.post.dto.AccountOrgDto;
import com.koron.bean.system.post.query.PostUserQuery;
import com.koron.bean.system.post.vo.PostUserVo;
import com.koron.bean.system.role.RoleStaffBean;
import com.koron.bean.system.role.UserOwnJurisdictionBean;
import com.koron.bean.system.staff.Constant;
import com.koron.bean.system.staff.StaffBean;
import com.koron.bean.system.staff.dto.OutStaffBean;
import com.koron.bean.system.staff.dto.StaffBeanDto;
import com.koron.bean.system.staff.po.AppUserPo;
import com.koron.bean.system.staff.vo.AppUserVo;
import com.koron.bean.system.staff.vo.EamUser;
import com.koron.bean.util.RedisUtils;
import com.koron.bean.util.ServletUtils;
import com.koron.common.core.business.common.service.AttachmentService;
import com.koron.common.core.business.configsettings.utils.ConfigInfoTool;
import com.koron.common.core.business.langorguser.service.LangUserOrgConvertService;
import com.koron.common.core.business.system.MyRSAUtil;
import com.koron.common.core.business.system.SystemCacheUtil;
import com.koron.common.core.config.ThreadLocalContext;
import com.koron.common.core.util.CheckPassword;
import com.koron.common.core.util.HanyupinyinUtil;
import com.koron.common.core.util.IpUtil;
import com.koron.system.agent.business.bean.vo.AgentInfo;
import com.koron.system.agent.business.service.AgentService;
import com.koron.system.agent.service.AgentRoleUserService;
import com.koron.system.anno.VerifyStaff;
import com.koron.system.common.util.MD5Utils;
import com.koron.system.configSettings.post.service.PostUserService;
import com.koron.system.login.bean.dto.LockDto;
import com.koron.system.login.service.LoginInfoService;
import com.koron.system.org.service.OrgService;
import com.koron.system.role.service.RoleService;
import com.koron.system.staff.bean.WorkFlowUser;
import com.koron.system.staff.bean.convertor.AppUserConvertor;
import com.koron.system.staff.bean.dto.AppUserDto;
import com.koron.system.staff.bean.dto.ForgetPwDto;
import com.koron.system.staff.bean.dto.VerifyStaffCheckDto;
import com.koron.system.staff.mapper.StaffMapper;
import com.koron.system.staff.service.StaffService;
import com.koron.system.userOrg.bean.po.AppUserOrgPo;
import com.koron.system.userOrg.service.AppUserOrgService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.ADOConnection;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @ClassName StaffServiceImpl
 * @description
 * @Author zhouj
 * @Date 2021/7/6 14:28
 */
@Slf4j
@Transactional
@Service
public class StaffServiceImpl implements StaffService {

    @Autowired
    StaffMapper staffMapper;

    @Autowired
    RoleService roleService;

    @Autowired
    OrgService orgService;

    @Autowired
    private AttachmentService attachmentService;

    @Autowired
    AppUserOrgService appUserOrgService;

    @Autowired
    AgentRoleUserService agentRoleUserService;

    @Autowired
    AgentService agentService;

    @Autowired
    AppUserConvertor userConvertor;

    @Autowired
    LoginInfoService loginInfoService;

    @Autowired
    PostUserService postUserService;

    @Autowired
    private LangUserOrgConvertService languserorgconvertservice;

    @Override
    public int insertOrUpdate(AppUserPo appUserPo) {
        if (StringUtils.isNotEmpty(appUserPo.getName())) {
            appUserPo.setNamePy(HanyupinyinUtil.getPinyinString(appUserPo.getName()));
        }
        if (!StringUtils.isEmpty(appUserPo.getPassword())) {
            appUserPo.setPassword(MD5Utils.md5(appUserPo.getPassword()));
        } else {
            appUserPo.setPassword(getInitPassWord());
        }
        if (!CheckPassword.checkPassword(appUserPo.getPassword())) {
            //校验失败
            throw new RuntimeException("密码必须包含字母,数字,特殊字符");
        }
        int i;
        if (StringUtils.isEmpty(appUserPo.getId())) {
            i = staffMapper.insert(appUserPo);
        } else {
            i = staffMapper.update(appUserPo);
        }
        //入库用户组织关联表
        if (StringUtils.isEmpty(appUserPo.getOrgId())) {
            appUserOrgService.insert(appUserPo.getAccount(), "unsync");
        } else {
            appUserOrgService.deleteByAccount(appUserPo.getAccount());
            appUserOrgService.insert(appUserPo.getAccount(), appUserPo.getOrgId());
        }
        return i;
    }

    @Override
    public int insertUser(EamUser user, AppUserDto userDto, MultipartFile photo) {
        user.setCurrDs("_default");

        int i = 0;
        String uuid = userDto.getAccount();

        //有附件则新增
        if (photo != null) {
            List<Attachment> attachmentList = attachmentService.uploadAttachment(uuid, photo);
            if (!CollectionUtils.isEmpty(attachmentList)) {
                userDto.setPhoto(attachmentList.get(0).getPath());
            }
        }

        if (StringUtils.isEmpty(userDto.getId())) {
            AppUserVo appUserVo = staffMapper.queryStaffInfoWithMerge(uuid);
            Assert.isNull(appUserVo, "该账号已存在！");
            userDto.setId(uuid);
            userDto.setCreateBy(user.getAccount());
            userDto.setCreateByName(user.getName());
            userDto.setCreateTime(new Date());
            userDto.setNamePy(HanyupinyinUtil.getPinyinString(userDto.getName()));
            if (!StringUtils.isEmpty(userDto.getPassword())) {
                userDto.setPassword(MD5Utils.md5(userDto.getPassword()));
            } else {
                userDto.setPassword(getInitPassWord());
            }
            if (!CheckPassword.checkPassword(userDto.getPassword())) {
                //校验失败
                throw new RuntimeException("密码必须包含字母,数字,特殊字符");
            }
            i = staffMapper.insert(userDto);
            if (StrUtil.isNotBlank(userDto.getLang())) {
                // 姓名多语言
                ADOConnection.runTask(languserorgconvertservice, "buildUserLang", Boolean.class, userDto.getAccount(), userDto.getLang(), user.getAccount());
            }
            //入库用户组织关联表
            List<AppUserOrgPo> appUserOrgPos = userDto.getAppUserOrgPos();

            int i1 = appUserOrgService.updateBatch(appUserOrgPos);
        }

        return i;
    }

    @Override
    public int updateUser(EamUser user, AppUserDto userDto, MultipartFile photo, String delPhotoId) {

        int i = 0;
        user.setCurrDs("_default");

        if (!StringUtils.isEmpty(delPhotoId)) {
            attachmentService.deleteAttachment(userDto.getId());
            userDto.setPhoto(null);
        }

        if (photo != null) {
            List<Attachment> attachmentList = attachmentService.uploadAttachment(userDto.getId(), photo);
            if (!CollectionUtils.isEmpty(attachmentList)) {
                userDto.setPhoto(attachmentList.get(0).getId());
            }
        }

        if (!StringUtils.isEmpty(userDto.getId())) {
            userDto.setUpdateBy(user.getAccount());
            userDto.setUpdateByName(user.getName());
            userDto.setUpdateTime(new Date());
            if (StringUtils.isNotEmpty(userDto.getName())) {
                userDto.setNamePy(HanyupinyinUtil.getPinyinString(userDto.getName()));
            }

            i = staffMapper.update(userDto);

            //入库用户组织关联表
            List<AppUserOrgPo> appUserOrgPos = userDto.getAppUserOrgPos();

            int i1 = appUserOrgService.updateBatch(appUserOrgPos);
            if (StrUtil.isNotBlank(userDto.getLang())) {
                // 姓名多语言
                ADOConnection.runTask(languserorgconvertservice, "buildUserLang", Boolean.class, userDto.getAccount(), userDto.getLang(), user.getAccount());
            }
        }

        return i;
    }

    @Override
    public int delete(String id) {
        StaffBean staffBean = new StaffBean();
        staffBean.setId(id);
        StaffBean staffBean1 = staffMapper.queryStaffInfo(staffBean);
        int i = staffMapper.softDelete(id);
        //删除用户的角色信息
        roleService.deleteUserRole(staffBean1.getAccount(), null);
        //删除用户组织关联表
        appUserOrgService.deleteByAccount(staffBean1.getAccount());
        return i;
    }

    @Override
    public int deleteWithOrg(String id, String orgId) {

        AppUserVo appUserVo = staffMapper.queryStaffInfoWithMerge(id);

        Assert.notNull(appUserVo);

        if (!StringUtils.isEmpty(orgId)) {
            List<OrgVo> orgVoList = appUserVo.getOrgVoList();

            if (CollectionUtils.isNotEmpty(orgVoList)) {
                List<String> collect = orgVoList.stream().map(OrgVo::getId).collect(Collectors.toList());
                if (collect.size() > 1) {
                    //删除用户组织关联表
                    int i = appUserOrgService.deleteByAccount(id, orgId);
                    return i;
                }
            }
        }

        int i = staffMapper.softDelete(id);
        //删除用户的角色信息
        roleService.deleteUserRole(id, null);
        //删除用户组织关联表
        appUserOrgService.deleteByAccount(id);

        return i;
    }

    @Override
    public int deleteIds(List<String> ids, String orgId) {

        StaffBean staffBean = new StaffBean();
        staffBean.setAccountList(ids);

        List<String> less_accounts = new ArrayList<>();

        List<AppUserVo> appUserVos = queryStaffListByOrgWithMerge(0, staffBean, null, false);

        if (CollectionUtils.isEmpty(appUserVos)) {
            return 0;
        }

        List<String> accountList_all = appUserVos.stream().map(AppUserVo::getAccount).collect(Collectors.toList());

        //筛选 orgId为空或没有组织  或者组织大小为1且等于当前条件的组织
        List<AppUserVo> del1 = appUserVos.stream().filter(x -> StringUtils.isEmpty(orgId) || x.getOrgVoList().size() == 0 || (x.getOrgVoList().size() == 1 && x.getOrgVoList().get(0).getId().equals(orgId))).collect(Collectors.toList());

        if (CollectionUtils.isNotEmpty(del1)) {
            //取出账号
            List<String> account_1 = del1.stream().map(AppUserVo::getAccount).collect(Collectors.toList());

            //批量删除人员关联角色信息
            roleService.deleteUserRoleByUserIds(account_1);
            List<String> accountList = staffMapper.queryAccountListByUserIds(account_1);
            //批量删除人员关联组织信息
            appUserOrgService.deleteByAccountList(accountList, orgId);
            staffMapper.softDeleteIds(account_1);
            less_accounts = account_1;
        }

        //剩余多组织,只删除关联的组织即可
        accountList_all.removeAll(less_accounts);

        //批量删除人员关联组织信息
        if (!CollectionUtils.isEmpty(accountList_all)) {
            appUserOrgService.deleteByAccountList(accountList_all, orgId);
        }

        return ids.size();
    }

    @Override
    public List<StaffBean> queryStaffListByOrg(Integer cascadeQuery, StaffBeanDto staffBeanDto, PageQuery pageQuery) {

        String name = staffBeanDto.getName();

        if (StringUtils.isNotEmpty(name)) {
            staffBeanDto.setName(name.replace(" ", ""));
        }

        if (StringUtils.isNotBlank(staffBeanDto.getName()) && Pattern.matches("[a-zA-Z]*", staffBeanDto.getName())) {
            //如果是拼音
            String keyword = staffBeanDto.getName().toLowerCase();
            staffBeanDto.setName(null);
            staffBeanDto.setNamePy(keyword);
        }

        //引入权限控制--利用字段做控制,然后作为sql条件筛选
        if (staffBeanDto.getPermission()) {
            staffBeanDto.setOrgIds(getCurrUserOrgIds());
        }

        List<StaffBean> staffBeans = staffMapper.queryStaffListByOrg(cascadeQuery, staffBeanDto);

        //加入岗位信息
        //查询效率 一次性查出全部数据
        List<AccountOrgDto> accountOrgDtos = new ArrayList<>();

        if (CollectionUtils.isNotEmpty(staffBeans)) {
            List<Object> arrayList = new ArrayList<>();
            staffBeans.forEach(p -> {
                AccountOrgDto accountOrgDto = new AccountOrgDto();
                accountOrgDto.setAccount(p.getAccount());
                accountOrgDto.setOrgCode(p.getOrgId());
                accountOrgDtos.add(accountOrgDto);
            });
            PostUserQuery postUserQuery = new PostUserQuery();
            postUserQuery.setAccountOrgDtos(accountOrgDtos);
            postUserQuery.setPostName(staffBeanDto.getPostName());
            List<PostUserVo> postUserVos = postUserService.queryList(postUserQuery);

            //分类整理好,分别设置到人员信息
            if (CollectionUtils.isNotEmpty(postUserVos)) {
                Map<String, List<PostUserVo>> map = postUserVos.stream().collect(
                        Collectors.groupingBy(
                                p -> p.getUserAccount() + '-' + p.getOrgId()
                        ));
                staffBeans.forEach(p -> {
                    p.setPostUserVoList(map.get(p.getAccount() + '-' + p.getOrgId()));
                });
            }
        }

        return staffBeans;

    }

    @Override
    public Long queryStaffListByOrgCount(Integer cascadeQuery, StaffBean staffBean) {
        return staffMapper.queryStaffListByOrgCount(cascadeQuery, staffBean);
    }

    @Override
    public List<AppUserVo> queryStaffListByOrgWithMerge(Integer cascadeQuery, StaffBean staffBean, PageQuery pageQuery, Boolean isStsFlag) {

        List<AppUserVo> userVos = new ArrayList<>();

        String name = staffBean.getName();

        if (StringUtils.isNotEmpty(name)) {
            staffBean.setName(name.replace(" ", ""));
        }

        if (StringUtils.isNotBlank(staffBean.getName()) && Pattern.matches("[a-zA-Z]*", staffBean.getName())) {
            //如果是拼音
            String keyword = staffBean.getName().toLowerCase();
            staffBean.setName(null);
            staffBean.setNamePy(keyword);
        }

        List<String> orgIdlist = new ArrayList<>();
        if (isStsFlag) {
            orgIdlist = getCurrUserAllOrgIds();
        }
        List<AppUserVo> userVoList = staffMapper.queryStaffListByOrgWithMerge(cascadeQuery, staffBean, pageQuery, orgIdlist);

        if (CollectionUtils.isEmpty(userVoList)) {
            return userVos;
        }
        userVos = userVoList;
        List<String> accountList = userVos.stream().map(AppUserPo::getAccount).distinct().collect(Collectors.toList());

        //查询人员的组织信息
        List<AppUserOrgPo> userOrgPos = appUserOrgService.queryByAccountList(accountList);
        if (CollectionUtils.isNotEmpty(userOrgPos)) {
            Map<String, List<AppUserOrgPo>> userOrgMap = new HashMap<>();
            userOrgPos.forEach(p -> {
                if (CollectionUtils.isEmpty(userOrgMap.get(p.getAccount()))) {
                    userOrgMap.put(p.getAccount(), new ArrayList<>());
                }
                List<AppUserOrgPo> userOrgPos1 = userOrgMap.get(p.getAccount());
                userOrgPos1.add(p);
            });
            //组织id去重,查询所有组织信息
            List<String> orgIds = userOrgPos.stream().map(AppUserOrgPo::getOrgId).distinct().collect(Collectors.toList());
            List<OrgBean> orgList = orgService.queryByOrgIds(orgIds);
            if (CollectionUtils.isNotEmpty(orgList)) {
                Map<String, OrgBean> cond = new HashMap<>();
                //组织id --> 组织数据
                orgList.forEach(p -> cond.put(p.getId(), p));
                for (AppUserVo userVo : userVos) {
                    userVo.setOrgVoList(new ArrayList<>());
                    List<AppUserOrgPo> userOrgPos1 = userOrgMap.get(userVo.getAccount());
                    if (CollectionUtils.isNotEmpty(userOrgPos1)) {
                        //存在人员,组织对应关系
                        for (AppUserOrgPo userOrgPo : userOrgPos1) {
                            OrgVo orgVo = new OrgVo();
                            //遍历人员组织关系,查询对应的组织对象
                            OrgBean orgBean;
                            if (StringUtils.isNotBlank(userOrgPo.getOrgId()) && (orgBean = cond.get(userOrgPo.getOrgId())) != null){
                                orgVo = userConvertor.orgBeanToVo(orgBean);
                                //设置默认组织标识
                                orgVo.setDefaultFlag(userOrgPo.getDefaultFlag());
                                List<OrgVo> orgVoList = userVo.getOrgVoList();
                                orgVoList.add(orgVo);
                            }
                        }
                    }
                }
            }
        }

        //查询人员的岗位信息,设置到vo
        PostUserQuery postUserQuery = new PostUserQuery();
        postUserQuery.setUserAccountList(accountList);
        //账号list查询账号相关的岗位信息
        List<PostUserVo> postUserVos = postUserService.queryList(postUserQuery);
        if (CollectionUtils.isNotEmpty(postUserVos)) {
            Map<String, List<PostUserVo>> cond = new HashMap<>();
            postUserVos.forEach(p -> {

                if (CollectionUtils.isEmpty(cond.get(p.getUserAccount()))) {
                    cond.put(p.getUserAccount(), new ArrayList<>());
                }

                List<PostUserVo> postUserVoList = cond.get(p.getUserAccount());
                postUserVoList.add(p);
            });

            for (AppUserVo userVo : userVos) {
                userVo.setPostUserVoList(cond.get(userVo.getAccount()));
            }
        }
        return userVos;
    }

    @Override
    public Long queryStaffListByOrgWithMergeCount(Integer cascadeQuery, StaffBean staffBean) {

        return staffMapper.queryStaffListByOrgWithMergeCount(cascadeQuery, staffBean);
    }

    @Override
    public EamUser queryStaffInfo(String account) {
        String currOrg = ThreadLocalContext.getLoginUser().getCurrOrg();
        EamUser user = staffMapper.queryStaffInfoAccount(account, currOrg);
        //将人员的权限信息放进去
        if (user == null) {
            return null;
        }
        //查询单位的部门
        OrgBean orgBean = orgService.queryDeptByOrgId(user.getOrgId());
        if (!Objects.isNull(orgBean)) {
            user.setDeptId(orgBean.getId());
            user.setDeptName(orgBean.getName());
        }
        // 用户拥有权限
        UserOwnJurisdictionBean userOwnJurisdictionBean = roleService.queryUserOwnRoleJurisdiction(account);
        user.setUserOwnJurisdictionBean(userOwnJurisdictionBean);

        //放入组织下拉列表
        List<OrgVo> orgVos = queryOrgVoListByAccount(account);
        user.setOrgVoList(orgVos);
        //放入租户下拉列表
        List<AppSimpleBean> appSimpleBeanList = queryAppSimpleInfoListByAccount(account);
        user.setAppSimpleBeanList(appSimpleBeanList);
        //放入身份下拉列表
        AgentInfo agentInfo = agentService.queryAgentInfo(account);
        List<AgentUserVo> agentUserVos = agentInfo.getAgentLeaderPoList();
        user.setLeaderUserVos(agentUserVos);

        //放入岗位下拉列表
        PostUserQuery postUserQuery = new PostUserQuery();
        postUserQuery.setUserAccount(account);
        List<PostUserVo> postUserVos = postUserService.queryList(postUserQuery);
        user.setPostUserVoList(postUserVos);

        user.setPassword(null);

        return user;
    }

    @Override
    public EamUser queryAgentStaffInfo(String account) {

        EamUser agent = getCurrUser().getAgent();
        String currOrg = "";
        String currLeader = "";
        if (Objects.isNull(agent)) {
            //代理对象为空 查询代理领导信息,角色信息替换为已授权
            currOrg = ThreadLocalContext.getLoginUser().getCurrLeaderOrg();
            currLeader = ThreadLocalContext.getLoginUser().getCurrLeader();
        } else {
            currOrg = agent.getCurrLeaderOrg();
            currLeader = agent.getCurrLeader();
        }

        EamUser user = staffMapper.queryStaffInfoAccount(currLeader, currOrg);
        //将人员的权限信息放进去
        if (Objects.isNull(user)) {
            return null;
        }
        OrgBean orgBean = orgService.queryDeptByOrgId(user.getOrgId());
        if (!Objects.isNull(orgBean)) {
            user.setDeptId(orgBean.getId());
            user.setDeptName(orgBean.getName());
        }
        //先查询 该账号代理的roleIds
        AgentRoleUserPo agentRoleUserPo = new AgentRoleUserPo();
        agentRoleUserPo.setAgent(account);
        agentRoleUserPo.setLeader(currLeader);
        List<AgentRoleUserPo> agentRoleUserPos = agentRoleUserService.queryList(agentRoleUserPo);
        List<String> roleIds = agentRoleUserPos.stream().map(AgentRoleUserPo::getRoleId).collect(Collectors.toList());

        UserOwnJurisdictionBean userOwnJurisdictionBean = roleService.queryUserOwnRoleJurisdictionWithRoleIds(currLeader, roleIds);
        user.setUserOwnJurisdictionBean(userOwnJurisdictionBean);

        //放入组织下拉列表
        List<OrgVo> orgVos = queryOrgVoListByAccount(currLeader);
        user.setOrgVoList(orgVos);
        //放入租户下拉列表
        List<AppSimpleBean> appSimpleBeanList = userOwnJurisdictionBean.getAppSimpleBeanList();
        user.setAppSimpleBeanList(appSimpleBeanList);
        //放入岗位下拉列表
        PostUserQuery postUserQuery = new PostUserQuery();
        postUserQuery.setUserAccount(currLeader);
        List<PostUserVo> postUserVos = postUserService.queryList(postUserQuery);
        user.setPostUserVoList(postUserVos);

        user.setPassword(null);

        return user;
    }

    @Override
    public AppUserVo queryStaffInfoWithMerge(String account) {
        AppUserVo userVo = staffMapper.queryStaffInfoWithMerge(account);

        if (userVo == null) {
            return null;
        }

        //查询组织上级部门
        List<OrgVo> orgVoList = userVo.getOrgVoList();
        if (CollectionUtils.isNotEmpty(orgVoList)) {
            for (OrgVo orgVo : orgVoList) {
                OrgBean orgBean = orgService.queryDeptByOrgId(orgVo.getId());
                if (!Objects.isNull(orgBean)) {
                    orgVo.setDeptId(orgBean.getId());
                    orgVo.setDeptName(orgBean.getName());
                }
            }
        }
        //设置应用对象列表
        List<AppSimpleBean> appSimpleBeans = roleService.queryAppJurisdictionByAccount(account);
        if (CollectionUtils.isNotEmpty(appSimpleBeans)) {
            userVo.setAppSimpleBeanList(appSimpleBeans);
        }

        //放入岗位下拉列表
        PostUserQuery postUserQuery = new PostUserQuery();
        postUserQuery.setUserAccount(account);
        List<PostUserVo> postUserVos = postUserService.queryList(postUserQuery);
        userVo.setPostUserVoList(postUserVos);

        return userVo;
    }

    @Override
    public List<OrgVo> queryOrgVoListByAccount(String account) {
        List<OrgVo> orgVos = staffMapper.queryOrgVoListByAccount(account);

        return orgVos;
    }

    @Override
    public List<AppSimpleBean> queryAppSimpleInfoListByAccount(String account) {
        List<AppSimpleBean> appSimpleBeans = new ArrayList<>();
        //设置应用对象列表
        appSimpleBeans = roleService.queryAppJurisdictionByAccount(account);

        return appSimpleBeans;
    }

    @Override
    public StaffBean querySingleStaffInfo(StaffBean staffBean) {
        return staffMapper.queryStaffInfo(staffBean);
    }

    @Override
    public List<WorkFlowUser> getWorkFlowUserList() {
        return staffMapper.getWorkFlowUserList();
    }

    @Override
    public StaffBean querySingleStaffInfoByAccount(String account) {
        return staffMapper.queryStaffInfoAccount(account, null);
    }

    @Override
    public Response outStafflogin(OutStaffBean bean, HttpServletResponse response) {
        return outStafflogin(bean, response, true);
    }

    @Override
    public Response outStafflogin(OutStaffBean bean, HttpServletResponse response, Boolean needVerityCode) {
        HttpServletRequest request = ServletUtils.getRequest();
        String ipAddr = IpUtil.getIpAddr(request);
        String message = "登录成功";

        if (needVerityCode) {
            //先校验登录验证码(根据账号密码方式还是手机号方式区别)
            String verityCode = bean.getVerityCode();
            Assert.hasText(verityCode, "登录验证码不能为空");

            String redis_verityCode = (String) RedisUtils.hget(Constant.EAM_SERVICE_AUTH_VERIFYCODE, ipAddr);

            Assert.hasText(redis_verityCode, "登录验证码过期");

            Assert.isTrue(StringUtils.equalsIgnoreCase(verityCode, redis_verityCode), "登录验证码不正确");

        }

        //先对登录ip进行校验,是否锁定 是:直接返回  否进行下面校验
        LockDto lock = loginInfoService.isLock(bean.getAccount());
        if (lock.getIsLock()) {
            //锁定状态,直接返回前端
            return Response.fail("该ip已被锁定中,还剩下" + lock.getTimeLeft() + "分钟");
        }

        //私钥解密后,再 md5 与数据库中的密码比对
        String decrypt = null;
        try {
            decrypt = MyRSAUtil.decrypt(bean.getPassword());
        } catch (Exception e) {
            return Response.fail("密码未正确加密");
        }

        //先进行md5加密
        String str = MD5Utils.md5(decrypt);
        //账号是否存在
        bean.setPassword(null);
        StaffBean staffBean = staffMapper.verifyAccount(bean);
        if (staffBean == null) {
            //账号是否存在,提示信息
            return Response.fail("用户名或密码错误");
        }
        //账号是否存在
        if (!StringUtils.equals(staffBean.getPassword(), str)) {
            //密码是否一致,提示信息
            int remainTime = loginInfoService.insertOrUpdate(bean.getAccount());
            return Response.fail("用户名或密码错误,还有" + remainTime + "次机会");
        } else {
            //账号密码都是一致的,则刷新ip+account 数据
            loginInfoService.update(bean.getAccount());
            // 获取初始化密码
            Map<String, String> configByCode = ConfigInfoTool.getConfigByCode("system", "system_login_config");
            String initPassword = MD5Utils.md5(configByCode.getOrDefault("init_password", "Eam2@2022"));
            if (str.equals(initPassword)) {
                message = StrUtil.format("{}-{}", message, "请求修改密码");
            }
        }

        if (staffBean.getDeleteFlag() != null && staffBean.getDeleteFlag() == 1) {
            return Response.fail("该账号已被注销");
        }

        EamUser eamUser = queryStaffInfo(bean.getAccount());
        if (eamUser == null) {
            return Response.fail("该账号" + bean.getAccount() + "不存在");
        }
        //验证账号是否过期
        SystemCacheUtil.vertifyAccountExpire(eamUser);

        List<OrgVo> orgVoList = eamUser.getOrgVoList();
        List<AppSimpleBean> appSimpleBeanList = eamUser.getAppSimpleBeanList();

        if (CollectionUtils.isNotEmpty(orgVoList) && orgVoList.size() == 1
                && CollectionUtils.isNotEmpty(appSimpleBeanList)
                && appSimpleBeanList.size() == 1) {
            response.setHeader("SKIP_SIGN", "true");
            response.setHeader(Constant.DYNAMIC_AGENT_ORG, orgVoList.get(0).getId());
            response.setHeader(Constant.DYNAMIC_DATA_SOURCE, appSimpleBeanList.get(0).getAppMark());
        }

        //登陆过后马上生成token返回前端,作为业务开始
        String token = SystemCacheUtil.getNewToken(bean.getAccount(), bean.getName());

        EamUser redisUser = SystemCacheUtil.getRedisUser(bean.getAccount());
        if (Objects.isNull(redisUser)) {
            //token有效,但redis数据被删除
            if (!StringUtils.isEmpty(token)) {
                List<String> list = new ArrayList<>();
                list.add(token);
                eamUser.setTokenList(list);
            }
        } else {
            //缺少菜单信息
            List<String> redisTokenList = redisUser.getTokenList();
            if (CollectionUtils.isEmpty(redisTokenList)) {
                redisTokenList = new ArrayList<>();
            }
            redisTokenList.add(token);
            eamUser.setTokenList(redisTokenList);
        }
        SystemCacheUtil.cacheUserInfo(eamUser);
        response.setHeader(Constant.JWT_TOKEN, token);

        return Response.success(message, bean.getAccount());
    }

    @Override
    public Response outStaffloginByPhone(OutStaffBean bean, HttpServletResponse response) {
        HttpServletRequest request = ServletUtils.getRequest();
        String ipAddr = IpUtil.getIpAddr(request);

        //先校验登录验证码(根据账号密码方式还是手机号方式区别)
        String verityCode = bean.getVerityCode();
        Assert.hasText(verityCode, "登录验证码不能为空");

        String redis_verityCode = (String) RedisUtils.hget(Constant.EAM_SERVICE_SYSTEM_LOGIN_VERIFYCODE, bean.getPhone());

        Assert.hasText(redis_verityCode, "登录验证码过期");

        Assert.isTrue(StringUtils.equalsIgnoreCase(verityCode, redis_verityCode), "登录验证码不正确");

        //先对登录ip进行校验,是否锁定 是:直接返回  否进行下面校验
        LockDto lock = loginInfoService.isLock(bean.getAccount());
        if (lock.getIsLock()) {
            //锁定状态,直接返回前端
            return Response.fail("该ip已被锁定中,还剩下" + lock.getTimeLeft() + "分钟");
        }

        //账号是否存在
        bean.setPassword(null);
        StaffBean staffBean = staffMapper.verifyAccount(bean);

        Assert.isTrue(staffBean != null, "不存在该手机号的用户");

        Assert.isTrue(staffBean.getDeleteFlag() == 0, "该账号已被注销");

        String account = staffBean.getAccount();

        EamUser eamUser = queryStaffInfo(account);

        //验证账号是否过期
        SystemCacheUtil.vertifyAccountExpire(eamUser);

        List<OrgVo> orgVoList = eamUser.getOrgVoList();
        List<AppSimpleBean> appSimpleBeanList = eamUser.getAppSimpleBeanList();

        if (CollectionUtils.isNotEmpty(orgVoList) && orgVoList.size() == 1
                && CollectionUtils.isNotEmpty(appSimpleBeanList)
                && appSimpleBeanList.size() == 1) {
            response.setHeader("SKIP_SIGN", "true");
        }

        //登陆过后马上生成token返回前端,作为业务开始
        String token = SystemCacheUtil.getNewToken(account, bean.getName());

        EamUser redisUser = SystemCacheUtil.getRedisUser(account);
        if (Objects.isNull(redisUser)) {
            //token有效,但redis数据被删除
            if (!StringUtils.isEmpty(token)) {
                List<String> list = new ArrayList<>();
                list.add(token);
                eamUser.setTokenList(list);
            }
        } else {
            //缺少菜单信息
            List<String> redisTokenList = redisUser.getTokenList();
            if (CollectionUtils.isEmpty(redisTokenList)) {
                redisTokenList = new ArrayList<>();
            }
            redisTokenList.add(token);
            eamUser.setTokenList(redisTokenList);
        }
        SystemCacheUtil.cacheUserInfo(eamUser);
        response.setHeader(Constant.JWT_TOKEN, token);

        return Response.success("登陆成功", account);
    }

    @Override
    public List<String> queryAccountByStaffOrOrgList(List<RoleStaffBean> list1, List<RoleStaffBean> list2) {

        if (CollectionUtils.isEmpty(list1) && CollectionUtils.isEmpty(list2)) {
            return null;
        }

        return staffMapper.queryAccountByStaffOrOrgList(list1, list2);
    }

    @Override
    public int resetPy() {

        List<StaffBean> listByOrg = queryStaffListByOrg(1, new StaffBeanDto(), null);
        listByOrg.forEach(p -> {
            p.setNamePy(HanyupinyinUtil.getPinyinString(p.getName()));
        });
        if (CollectionUtils.isEmpty(listByOrg)) {
            return 0;
        }

        return staffMapper.resetPy(listByOrg);
    }

    @Override
    public int clearDefaultAppId(String defaultAppId) {
        return staffMapper.clearDefaultAppId(defaultAppId);
    }

    @VerifyStaff
    @Override
    public Response verifyStaffInfo(OutStaffBean outStaffBean) {
        //校验输入的账号及密码
        String password = outStaffBean.getPassword();
        Assert.hasText(outStaffBean.getPassword(), "密码不能为空");


        outStaffBean.setPassword(null);
        StaffBean staffBean = staffMapper.verifyAccount(outStaffBean);

        if (staffBean == null  && outStaffBean.getType() == null) {
            return Response.fail("不存在该账号");
        }

        if (staffBean == null && outStaffBean.getType().equals("ticket")) {
            return Response.ok(new VerifyStaffCheckDto("noexist","不存在该账号"));
        }

        if (staffBean.getDeleteFlag() == 1) {
            return Response.fail("该账号已被注销");
        }

        //私钥解密后,再 md5 与数据库中的密码比对
        String decrypt = null;
        try {
            decrypt = MyRSAUtil.decrypt(password);
        } catch (Exception e) {
            return Response.fail("密码未正确加密");
        }

        String str = MD5Utils.md5(decrypt);

        if (!StringUtils.equals(staffBean.getPassword(), str)) {
            return Response.fail("密码有误");
        }
        AppUserVo appUserVo = queryStaffInfoWithMerge(staffBean.getAccount());
        appUserVo.setPassword(null);
        return Response.ok("校验成功", appUserVo);
    }

    @Override
    public Response verifyAccountPassword(String account, String password) {
        OutStaffBean outStaffBean = new OutStaffBean();
        outStaffBean.setAccount(account);
        outStaffBean.setPassword(password);

        //校验输入的账号及密码
        Assert.hasText(password, "密码不能为空");
        outStaffBean.setPassword(null);
        StaffBean staffBean = staffMapper.verifyAccount(outStaffBean);

        if (staffBean == null  && outStaffBean.getType() == null) {
            return Response.fail("不存在该账号");
        }

        if (staffBean == null && outStaffBean.getType().equals("ticket")) {
            return Response.ok(new VerifyStaffCheckDto("noexist","不存在该账号"));
        }

        if (staffBean.getDeleteFlag() == 1) {
            return Response.fail("该账号已被注销");
        }

        String str = MD5Utils.md5(password);

        if (!StringUtils.equals(staffBean.getPassword(), str)) {
            return Response.fail("密码有误");
        }
        return Response.ok("校验成功", outStaffBean);
    }

    @Override
    public Response resetPw(String account, String password, String prePassword) {

        if (StringUtils.isNotEmpty(prePassword)) {
            //传入旧密码,对旧密码进行校验
            OutStaffBean outStaffBean = new OutStaffBean();
            outStaffBean.setAccount(account);
            outStaffBean.setPassword(prePassword);
            Response response = verifyStaffInfo(outStaffBean);
            if (response == null || response.getCode() != 200) {
                return response;
            }
        }

        //私钥解密后,再 md5 与数据库中的密码比对
        String decrypt_pw = null;
        try {
            decrypt_pw = MyRSAUtil.decrypt(password);
        } catch (Exception e) {
            return Response.fail("密码未正确加密");
        }
        //这里对密码进行校验
        if (!CheckPassword.checkPassword(decrypt_pw)) {
            //校验失败
            return Response.fail("密码必须包含字母,数字,特殊字符");
        }

        String md5 = MD5Utils.md5(decrypt_pw);

        int i = staffMapper.resetPw(account, md5);

        return Response.ok(i);
    }

    /*
     * 功能描述 批量新增人员,人员允许多个组织,人员信息存在一条,用户组织关联表多条
     * @author zhouj
     * @date 2021/7/8 10:53
     * @param [user, staffBeans]
     * @return int
     */
    @Override
    public int batchInUpUser(EamUser user, List<AppUserPo> userPos) {

        //1.入库人员信息
        userPos.forEach(p -> {
            p.setId(p.getAccount());
            p.setCreateBy(user.getAccount());
            p.setCreateByName(user.getName());
            p.setCreateTime(new Date());
            p.setNamePy(HanyupinyinUtil.getPinyinString(p.getName()));
            if (!StringUtils.isEmpty(p.getPassword())) {
                //                //批量接口  只有外单位审核(密码已被加密过)/内单位多个勾选(使用初始密码)
                /*p.setPassword(p.getPassword());*/
            } else {
                p.setPassword(getInitPassWord());
            }
        });
        //2.入库用户组织关联表
        List<AppUserOrgPo> userOrgPos = userPos.stream().map(userPo -> {
            AppUserOrgPo userOrgPo = new AppUserOrgPo();
            //将userCheckPO拷贝给userCheckData
            BeanUtils.copyProperties(userPo, userOrgPo);
            userOrgPo.setId(null);
            return userOrgPo;
        }).collect(Collectors.toList());
        int i = appUserOrgService.insertBatch(userOrgPos);

        return staffMapper.batchInsert(userPos);
    }

    @Override
    public String getInitPassWord() {

        Map<String, String> configByCode = ConfigInfoTool.getConfigByCode("system", "system_login_config");

        return MD5Utils.md5(configByCode.getOrDefault("init_password", "hello123&"));
    }

    @Override
    public Response forgetPw(ForgetPwDto forgetPwDto) {

        String phone = forgetPwDto.getPhone();
        //校验验证码是否正确
        String verity = (String) RedisUtils.hget("eam-service-system-forget-VerifyCode", forgetPwDto.getPhone());

        Assert.hasText(verity, "验证码过期");
        Assert.isTrue(StringUtils.equals(verity, forgetPwDto.getVerityCode()), "验证码不正确");

        //1.校验手机号是否在系统中存在
        StaffBean staffBean = new StaffBean();
        staffBean.setPhone(phone);
        StaffBean staffBean1 = querySingleStaffInfo(staffBean);
        Assert.notNull(staffBean1, "不存在该手机号的用户");
        //2.修改密码
        return resetPw(staffBean1.getAccount(), forgetPwDto.getPassword(), null);
    }

}
